<template>
  <div class="transfer-wrap">
    <show-box :boxWidth="275" class="transfer-left">
      <template slot="card-header">
        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" />
        <h4>{{ leftTitle }}</h4>
      </template>
      <template slot="card-body">
        <div class="header-search-wrap">
          <slot name="box-header">
            <template v-if="showSearch">
              <el-input
                v-model="searchVal"
                placeholder="请输入搜索内容"
                @keyup.enter.native="handleSearchVal"
              >
                <i
                  slot="suffix"
                  class="el-input__icon el-icon-search search-btn"
                  @click.stop="handleSearchVal"
                />
              </el-input>
            </template>
          </slot>
        </div>
        <el-checkbox-group
          v-model="checkedCodeList"
          class="left-list-wrap"
          @change="handleCheckeChange"
        >
          <el-checkbox
            v-for="item in sourceList"
            :key="item[sourceProps.key]"
            :label="item[sourceProps.key]"
          >
            <span v-if="item[sourceProps.code]" class="code-label" >
              {{ item[sourceProps.code] }}
            </span>
            <span>{{ item[sourceProps.label] }}</span>
          </el-checkbox>
        </el-checkbox-group>
        <div class="footer-wrap">
          <slot name="left-footer"></slot>
        </div>
      </template>
    </show-box>
    <div class="transfer-center">
      <i class="el-icon-arrow-right arrow-icon" />
    </div>
    <show-box cardHeaderJustify="end" :boxWidth="275" class="transfer-right">
      <template slot="card-header">
        <h4>{{ rightTitle }}</h4>
      </template>
      <template slot="card-body">
        <div class="right-list-wrap">
          <ul v-for="(item, index) in selectedList" :key="item[sourceProps.key]">
            <li class="result-row">
              <div>
                <span v-if="item[sourceProps.code]" class="code-label" >
                  {{ item[sourceProps.code] }}
                </span>
                <span>{{ item[sourceProps.label] }}</span>
              </div>
              <DeleteIcon @delete="handleDeleteSelected(item, index)" />
            </li>
          </ul>
        </div>
        <div class="footer-wrap">
          <slot name="right-footer"></slot>
        </div>
      </template>
    </show-box>
  </div>
</template>
<script>
import ShowBox from './ShowBox';
import DeleteIcon from './DeleteIcon';
import { TRANSFER_TYPE_VALUES } from '../constants';
export default {
  components: {
    ShowBox,
    DeleteIcon
  },
  props: {
    sourceProps: { // props属性
      type: Object,
      default: () => ({
        label: 'label',
        key: 'value',
        code: 'code'
      })
    },
    dataList: { // 列表数据集合
      type: Array,
      default: () => []
    },
    leftTitle: { // 左框标题
      type: String,
      default: ''
    },
    rightTitle: { // 右框标题
      type: String,
      default: ''
    },
    transferType: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      checkAll: false,
      isIndeterminate: false,
      checkedCodeList: [],
      sourceMaps: new Map(),
      selectedList: [],
      searchVal: '',
    }
  },
  watch: {
    transferType () {
      this.resetAll()
    }
  },
  computed: {
    sourceList () {
      this.dataList.forEach(item => {
        this.sourceMaps.set(item[this.sourceProps.key], item)
      })
      return [...this.dataList]
    },
    showSearch () {
      return this.transferType == TRANSFER_TYPE_VALUES.Brand
    },
  },
  methods: {
    resetAll () {
      this.selectedList = []
      this.checkAll = false
      this.isIndeterminate = false
      this.checkedCodeList = []
      this.sourceMaps = new Map()
      this.searchVal = ''
    },
    // 全选change
    handleCheckAllChange (val) {
      this.isIndeterminate = false
      this.checkedCodeList = val ? this.sourceList.map(item => item[this.sourceProps.key]) : []
      this.selectedList = val ? [...this.sourceList] : []
      val && this.$emit('updateCheckedAll')
    },
    // 单选change
    handleCheckeChange (codeList) {
      const checkedCount = codeList.length;
      this.checkAll = checkedCount === this.sourceList.length;
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.sourceList.length;
      this.selectedList = codeList
        .map(code => ({ ...this.sourceMaps.get(code) }))
        .filter(item => item)
      checkedCount > 0 && this.$emit('updateCheckedAll')
    },
    // 已选列表删除
    handleDeleteSelected (checkedItem, selectedIndex) {
      this.selectedList.splice(selectedIndex, 1)
      const curIndex = this.checkedCodeList.findIndex(code => code == checkedItem[this.sourceProps.key])
      curIndex != -1 && this.checkedCodeList.splice(curIndex, 1)
    },
    // 查询框查询
    handleSearchVal () {
      this.$emit('getSearchVal', this.searchVal)
    },
  }
}
</script>
<style lang="less" scoped>
/deep/ .el-checkbox-group {
  display: flex;
  flex-direction: column;
}
.transfer-wrap {
  display: flex;
  justify-content: space-between;
  .transfer-center {
    width: 30px;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0 10px;
  }
}

.header-search-wrap {
  display: flex;
  align-items: center;
  padding-bottom: 5px;
  margin-bottom: 5px;
  border-bottom: 1px dashed #ccc;
}
.left-list-wrap, .right-list-wrap {
  width: 100%;
  overflow: hidden;
  overflow-x: auto;
  overflow-y: auto;
}
.left-list-wrap {
  height: 490px;
}
.right-list-wrap {
  display: flex;
  flex-direction: column;
  height: 510px;
  .result-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 5px 0;
    margin-right: 5px;
    border-bottom: 1px dashed #ccc;
  }
  .code-label {
    margin-right: 10px;
  }
}
.footer-wrap {
  display: flex;
  flex-direction: column;
}
.search-btn {
  cursor: pointer;
  &:hover {
    color: #63a8fc;
  }
}
.arrow-icon {
  padding: 3px;
  border-radius: 4px;
  color: #fff;
  background-color: #909399;
}
</style>
